package com.test.aop.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Order(3)
@Aspect
@Component
@Slf4j
public class AspectDemo1 {

//    存在⼤量重复的切点表达式
//    execution(* com.example.demo.controller.*.*(..)) ,
//    Spring提供了 @PointCut 注解, 把公共的切点
//    表达式提取出来, 需要⽤到时引⽤该切⼊点表达式即可

//    当切点定义使⽤private修饰时, 仅能在当前切⾯类中使⽤, 当其他切⾯类也要使⽤当前切点定义时, 就需
//    要把private改为public. 引⽤⽅式为: 全限定类名.⽅法名()

//    @Order 控制切⾯的优先级, 先执⾏优先级较⾼的切⾯, 再执⾏优先级较低的切⾯, 最终执⾏⽬标⽅法

    @Pointcut("execution(* com.test.aop.controller.*.*(..))")
    public void pt(){}

    @Around("pt()")
    public void doAround(ProceedingJoinPoint pjp) throws Throwable {
        log.info("AspectDemo1的Around通知中目标方法执行之前");
        Object result = pjp.proceed();
        log.info("Around通知中目标方法执行之后");
    }

    @After("pt()")
    public void doAfter(){
        log.info("AspectDemo1的doAfter");
    }

    @Before("pt()")
    public void doBefore(){
        log.info("AspectDemo1的doBefore");
    }

    @AfterReturning("pt()")
    public void doAfterReturning(){
        log.info("AspectDemo1的doAfterReturning");
    }

    @AfterThrowing("pt()")
    public void doAfterThrowing(){
        log.info("AspectDemo1的doAfterThrowing");
    }

}
